package main

import "fmt"

/*
封装书的结构体，属性有：书名、价格、作者、状态；
封装读者类，属性有：ReaderID，押金余额；方法有：借书、还书、交罚款；
封装学生类：继承读者类，拓展专业属性、学习方法；
封装老师类：继承读者类，拓展课程属性、教学方法，修改交罚款方法（老师不用交罚款）；
*/

type Book struct {
	Name   string
	Price  float64
	Author string
	Borrowable bool
}

type Reader struct {
	//读者ID
	ReaderID string
	//押金余额
	Balance float64
}

/*借书*/
func (r *Reader) BorrowBook(b *Book) {
	if b.Borrowable{
		b.Borrowable = false
		fmt.Printf("读者%s借阅了%s\n", r.ReaderID, b.Name)
	}else{
		fmt.Printf("借阅失败，%s不在馆\n")
	}
}

/*还书*/
func (r *Reader) ReturnBook(b *Book) {
	fmt.Printf("读者%s归还了%s\n", r.ReaderID, b.Name)
}

/*交罚金*/
func (r *Reader) PayPenalty(amount float64) {
	r.Balance -= amount
	fmt.Printf("读者%s交纳了罚金%.2f元，它的余额是%.2f\n", r.ReaderID, amount, r.Balance)
}

/*学生数据模型*/
type Student struct {
	//继承Reader
	Reader
	//学生特有属性——姓名、专业
	Name  string
	Major string
}

func (s *Student) Study() {
	fmt.Printf("%s正在学习\n", s.Name)
}

/*老师数据模型*/
type Teacher struct {
	//继承Reader
	Reader
	//老师特有属性——姓名、课程
	Name   string
	Course string
}

func (t *Teacher) Teach() {
	fmt.Printf("%s正在教授%s\n", t.Name, t.Course)
}

/*覆写交罚金方法：老师不存在交罚金*/
func (t *Teacher) PayPenalty(amount float64) {
	//t.Balance -= amount
	fmt.Printf("读者%s交纳了罚金%.2f元，它的余额是%.2f\n", t.ReaderID, amount, t.Balance)
}

func main() {

	/*创建书*/
	b1 := Book{}
	b1.Name = "瓶中梅"
	b1.Author = "蓝领小生"
	b1.Price = 50.0
	b1.Borrowable = true

	b2 := Book{"一个老师的自我修养", 23.0, "空姐",true}
	b3 := Book{Price: 100, Name: "明朝那些事儿"}
	b3.Borrowable = true

	b4Ptr := new(Book)
	b4Ptr.Name = "红楼梦"
	b4Ptr.Author = "曹雪芹"
	b4Ptr.Borrowable = true
	b4Ptr.Price = 45.0

	fmt.Println(b1,b2,b3,b4Ptr)

	/*创建学生和老师*/
	r1 := Reader{"001", 100}
	s1 := Student{r1, "狗剩", "Python"}
	fmt.Printf("%v\n",s1)
	fmt.Printf("%+v\n",s1)
	fmt.Printf("%#v\n",s1)

	t1 := Teacher{Reader{"002", 0}, "老王", "撩妹秘籍"}
	fmt.Printf("%+v\n",t1)

	/*教学、学习、借书、还书、交罚款*/
	t1.Teach()
	s1.Study()
	t1.BorrowBook(&b1)
	t1.BorrowBook(&b2)
	s1.BorrowBook(&b3)
	s1.BorrowBook(b4Ptr)
	t1.ReturnBook(&b1)
	s1.ReturnBook(b4Ptr)
	s1.PayPenalty(5)
}
